
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
    Part of Seagull - The Pyhon Pages engine
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    page_lookup:
      Looks up the pages from the available page providers.
"""
__author__ = 'Jonathan Slenders <jonathan at slenders dot be>'
__license__ = 'GNU LGPL'
__all__ = ('PageLookup', 'PageNotFoundException')

import posixpath

from configuration import SystemConfig
import page_providers

class PageLookup(object):
	"""
	Finds the matching classname for a given page
	"""
	__pages_dictionary = None

	def __init__(self):
		self._config = SystemConfig()

	def resolve_page(self, path):
		"""
		Looks for a page matching this path in all the
		page providers.
		Returns page_providers.PythonPage/BinaryPage
		"""
		assert(isinstance(path, unicode))

		# Normalize path
		path = u'%s' % posixpath.normpath(path)

		# Ask each provider for this page
		for provider in self._config.page_providers:
			try:
				return provider.lookup_page(path)

			except page_providers.PageNotFoundException:
				pass

		raise PageNotFoundException(path)

	def initialize_page(self, pythonpage, server_interface, placeholder_implementations = { }, parameters = { }, caller=None, child = None, instance_id=None):
		assert(isinstance(pythonpage, page_providers.PythonPage))

		if instance_id == None: instance_id = pythonpage.path
		
		# Recompile page when it's been changed
		if pythonpage.has_been_changed():
			import page_compiler,sys
			page_compiler.PageCompiler().compile_page(pythonpage)

		# Read source code
		script = pythonpage.get_compiled_page()

		# Exec page, and retreive CompiledPage object
		globals = { }
		exec (compile(script, 'Python Page: %s' % pythonpage.path, 'exec'), globals)
		page_object = globals['CompiledPage']

		# Create instance of page
		return page_object(server_interface, placeholder_implementations, parameters, caller=caller, child=child, instance_id=instance_id)


class PageNotFoundException(Exception):
	def __init__(self, path):
		Exception.__init__(self, 'Page %s could not be found' % path)
		self.path = path

